

#include "IO.h"
#include "BSP.h"

#define SPI_MOSI_GPIO		GPIOC
#define SPI_MOSI_PIN		GPIO_PIN_4

#define SPI_MISO_GPIO		GPIOC
#define SPI_MISO_PIN		GPIO_PIN_5

#define SPI_SCK_GPIO		GPIOC
#define SPI_SCK_PIN			GPIO_PIN_6


static const IO_T SPI_MOSI = {(void*)SPI_MOSI_GPIO, SPI_MOSI_PIN};
static const IO_T SPI_MISO = {(void*)SPI_MISO_GPIO, SPI_MISO_PIN};
static const IO_T SPI_SCK = {(void*)SPI_SCK_GPIO, SPI_SCK_PIN};

static uint32_t SPI_SCK_Time;

#define SPI_MOSI_SetState(state) 	BSP_IO_Set(SPI_MOSI_GPIO, SPI_MOSI_PIN, state)
#define SPI_MISO_GetState() 		BSP_IO_Get(SPI_MISO_GPIO, SPI_MISO_PIN)
#define SPI_CLK_SetState(state) 	BSP_IO_Set(SPI_SCK_GPIO, SPI_SCK_PIN, state)


#define SPI_ExchangeBit(send, receive, num) { \
	if((send) & (0x80 >> (num))){	SPI_MOSI_SetState(1u);} \
	else{SPI_MOSI_SetState(0u);} \
	BSP_Delay_us(SPI_SCK_Time);	SPI_CLK_SetState(1);	\
	if(SPI_MISO_GetState()){(receive) |= (0x80 >> (num));}	\
	BSP_Delay_us(SPI_SCK_Time);	SPI_CLK_SetState(0); \
}

#define taskENTER_CRITICAL()
#define taskEXIT_CRITICAL()

void BSP_SwSPI_Init(uint32_t sckTime){
	IO_Init(&SPI_SCK, IO_Mode_OUT);
	IO_Init(&SPI_MISO, IO_Mode_IN);
	IO_Init(&SPI_MOSI, IO_Mode_OUT);
	SPI_SCK_Time = sckTime;
}


uint8_t BSP_SwSPI_TxRx(uint8_t send){
    uint8_t receive = 0; 
    
	taskENTER_CRITICAL();
    SPI_CLK_SetState(0);
	SPI_ExchangeBit(send, receive, 0);
	SPI_ExchangeBit(send, receive, 1);
	SPI_ExchangeBit(send, receive, 2);
	SPI_ExchangeBit(send, receive, 3);
	SPI_ExchangeBit(send, receive, 4);
	SPI_ExchangeBit(send, receive, 5);
	SPI_ExchangeBit(send, receive, 6);
	SPI_ExchangeBit(send, receive, 7);
	taskEXIT_CRITICAL();

    return receive;
}



